#include <task.h>


/******************************************************************************
* 函数名称: SwitchTo(TASK* task)
* 功能说明: 切换到任务 task 执行
* 输入参数: TASK*	task	--任务指针
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET SwitchTo(TASK* task)
{
    // 取任务上下文(寄存器)基址
    U32* reg_base = (U32*)(&task->reg);

    // 检查参数合法性
    if(NULL == task || NULL == reg_base)
        return E_ERR;
    
    // 恢复上下文
    asm volatile(
                "movl %0, %%esp\n"      // 先将栈顶指针 esp 指向任务上下文 reg 的起始位置
                "popl %%gs\n"
                "popl %%fs\n"
                "popl %%es\n"
                "popl %%ds\n"
                
                "popal\n"               // popal(gcc) = popad(nasm)
                // "popl %%edi\n"
                // "popl %%esi\n"
                // "popl %%ebp\n"
                // "addl $4, %%esp\n"   // 跳过 esp 寄存器本身的恢复
                // "popl %%ebx\n"
                // "popl %%edx\n"
                // "popl %%ecx\n"
                // "popl %%eax\n"
                
                "iret\n"
                :
                : "r"(reg_base)         // %0 替换成 reg_base
                :
                );
}

